﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Tea.Parser {

    /// <summary>
    /// 用于生成语法树的工具。
    /// </summary>
    public class Parser {

       // #region 成员

       // /// <summary>
       // /// 当前扫描器。
       // /// </summary>
       // ScannerBase _scanner;

       // /// <summary>
       // /// 当前作用域。
       // /// </summary>
       // IScopeNode _currentScope;

       // /// <summary>
       // /// 当前跳转语句。
       // /// </summary>
       // BreakableStatement _breakableBlock;

       // /// <summary>
       // /// 是否检查当前是否启用严格模式。
       // /// </summary>
       // bool _checkStrictMode = true;

       // /// <summary>
       // /// 获取当前的扫描器。
       // /// </summary>
       // public ScannerBase Scanner {
       //     get {
       //         return _scanner;
       //     }
       // }

       // /// <summary>
       // /// 获取当前的脚本域。
       // /// </summary>
       // public IScopeNode CurrentScript {
       //     get {
       //         return _currentScope;
       //     }
       // }

       // /// <summary>
       // /// 获取当前的错误数。
       // /// </summary>
       // public int ErrorCount {
       //     get {
       //         return ErrorReporter.ErrorCount;
       //     }
       // }

       // /// <summary>
       // /// 获取当前的警告数。
       // /// </summary>
       // public int WarnCount {
       //     get {
       //         return ErrorReporter.WarningCount;
       //     }
       // }

       // /// <summary>
       // /// 获取或设置当前错误报告工具。
       // /// </summary>
       // public IErrorReporter ErrorReporter {
       //     get;
       //     set;
       // }

       // #endregion

       // #region 设置


       // bool _isStrictMode;

       // /// <summary>
       // /// 获取或设置当前转换器是否为严格模式。
       // /// </summary>
       // public bool IsStrictMode {
       //     get {
       //         return _isStrictMode;
       //     }
       //     set {
       //         _isStrictMode = _scanner.IsStrictMode = value;
       //     }
       // }

       // /// <summary>
       // /// 获取或设置是否保留括号。
       // /// </summary>
       // public bool DoParseParamExpression {
       //     get;
       //     set;
       // }

       // #endregion

       // #region 工具

       // void WarningStrict(string msg) {
       //     ErrorReporter.WarningStrict(msg, _scanner.CurrentToken.StartLocation, _scanner.CurrentToken.EndLocation);
       // }

       // void WarningStrict(string msg, params string[] args) {
       //     WarningStrict(String.Format(msg, args));
       // }


       // void Warning(string msg) {
       //     ErrorReporter.Warning(msg, _scanner.CurrentToken.StartLocation, _scanner.CurrentToken.EndLocation);
       // }

       // void Warn(string msg, params string[] args) {
       //     Warning(String.Format(msg, args));
       // }

       // void Error(string msg, params string[] args) {
       //     Error(String.Format(msg, args));
       // }

       // void Error(string msg) {
       //     ErrorReporter.Error(msg, _scanner.CurrentToken.StartLocation, _scanner.CurrentToken.EndLocation);
       // }


       // #endregion

       // #region 解析

       // /// <summary>
       // /// 初始化 <see cref="Tea.Parser.Parser"/> 的新实例。
       // /// </summary>
       // public Parser()
       //     : this(new Scanner(), new DefaultErrorReporter()) {


       // }

       // /// <summary>
       // /// 初始化 <see cref="Tea.Parser.Parser"/> 的新实例。
       // /// </summary>
       // public Parser(ICommentParser commentParser, IErrorReporter errorReporter)
       //     : this(new Scanner(commentParser), errorReporter) {


       // }

       // /// <summary>
       // /// 初始化 <see cref="Tea.Parser.Parser"/> 的新实例。
       // /// </summary>
       // /// <param name="source">输入源。</param>
       // /// <param name="errorReporter">用于输出错误信息的工具。</param>
       // public Parser(ScannerBase source, IErrorReporter errorReporter) {
       //     DoParseParamExpression = true;
       //     ErrorReporter = errorReporter;
       //     _scanner = source;
       // }

       // /// <summary>
       // /// 解析指定的文档 。
       // /// </summary>
       // /// <param name="souceCode">要操作的字符串。</param>
       // /// <returns></returns>
       // public Script ParseString(string souceCode) {
       //     return Parse(new StringBuffer(souceCode));
       // }

       // public Script ParseFile(string fileName, Encoding encoding = null) {
       //     using (StreamBuffer sb = new StreamBuffer(fileName, encoding))
       //         return Parse(sb);
       // }

       // public Script ParseUri(Uri uri, Encoding encoding = null) {
       //     using (StreamBuffer sb = new StreamBuffer(CorePlus.IO.StreamHelper.GetStream(uri), encoding))
       //         return Parse(sb);
       // }

       // public Script ParseStream(System.IO.Stream input, Encoding encoding = null) {
       //     return Parse(new StreamBuffer(input, encoding));
       // }

       // /// <summary>
       // /// 解析指定的文档 。
       // /// </summary>
       // /// <param name="souceCode">要操作的字符串。</param>
       // /// <returns></returns>
       // public Script Parse(TextBuffer source) {
       //     _scanner.Source = source;
       //     return Parse(new Script(_scanner.Peek().StartLocation));
       // }

       // /// <summary>
       // /// 解析指定的扫描器。可选是否返回函数或脚本。
       // /// </summary>
       // /// <param name="source">要解析的源。</param>
       // /// <param name="sourceName">源名，如果是函数，则为函数名。否则是脚本名。</param>
       // /// <param name="returnFunction">如果是 true， 则返回函数。否则返回脚本。</param>
       // /// <returns>解析的结果。实现 IScope 的实例。</returns>
       // public IScopeNode Parse(TextBuffer source, bool returnFunction) {

       //     _scanner.Source = source;

       //     if (returnFunction) {
       //         return Parse(new FunctionExpression(String.Empty, new List<Identifier>(), _scanner.Peek().StartLocation));
       //     } else {
       //         return Parse(new Script(_scanner.Peek().StartLocation));
       //     }
       // }

       // /// <summary>
       // /// 进行解析。
       // /// </summary>
       // public Script Parse(Script script) {

       //     ErrorReporter.Clear();

       //     ParseProgram(script);

       //     script.endLocation = _scanner.CurrentToken.EndLocation;

       //     return script;

       // }

       // /// <summary>
       // /// 进行解析。
       // /// </summary>
       // public FunctionExpression Parse(FunctionExpression fn) {

       //     ParseProgram(fn);

       //     fn.endLocation = _scanner.CurrentToken.EndLocation;

       //     return fn;

       // }

       // /// <summary>
       // /// 如果下一个操作符和指定的操作符 <paramref name="token"/> 一致， 则移动到下一个操作符 。
       // /// </summary>
       // /// <param name="token">需要获取的操作符 。</param>
       // /// <returns>如果当前操作符符合指定的操作符且移动位置， 返回 true; 否则返回 false 。</returns>
       // bool MatchToken(TokenType token) {
       //     if (_scanner.Peek().Type == token) {
       //         _scanner.Read();
       //         return true;
       //     }

       //     return false;
       // }

       // /// <summary>
       // /// 确认下一个标识符是指定的标识符<paramref name="token"/>。
       // /// </summary>
       // /// <param name="token">期待的下一个操作符。</param>
       // /// <param name="message">错误信息。</param>
       // void AssertToken(TokenType token) {
       //     if (_scanner.Peek().Type != token) {
       //         Error(String.Format(Messages.ExpectedToken, Token.Find(token).Name));
       //     }
       // }

       // /// <summary>
       // /// 确保下一个 Token 为指定的 <paramref name="token"/> ，否则输出错误。
       // /// </summary>
       // /// <param name="token">期待的下一个操作符。</param>
       // /// <param name="message">错误信息。</param>
       // void ExpectToken(TokenType token, string message) {
       //     if (_scanner.Read().Type != token) {
       //         Error(message);
       //     }
       // }

       // /// <summary>
       // /// 确保下一个 Token 为指定的 <paramref name="token"/> ，否则输出错误。
       // /// </summary>
       // /// <param name="token">期待的下一个操作符。</param>
       // void ExpectToken(TokenType token) {
       //     if (_scanner.Read().Type != token) {
       //         Error(String.Format(Messages.ExpectedToken, Token.Find(token).Name));
       //     }
       // }

       // /// <summary>
       // /// 表示进入可中断循环(比如 break/continue 能直接搜索的)。
       // /// </summary>
       // /// <param name="loopLabel"></param>
       // /// <param name="doPushScope"></param>
       // /// <returns></returns>
       // private void EnterBlock(BreakableStatement block) {
       //     block.Parent = _breakableBlock;
       //     _breakableBlock = block;
       // }

       // /// <summary>
       // /// 表示离开一个中断循环块。
       // /// </summary>
       // private void ExitBlock() {
       //     _breakableBlock = _breakableBlock.Parent;
       // }

       // private BreakableStatement LookupBreakTarget() {
       //     return _breakableBlock;
       // }

       // private BreakableStatement LookupBreakTarget(string name) {
       //     for (BreakableStatement block = _breakableBlock; block != null; block = block.Parent) {
       //         if (block.Labels.Contains(name)) {
       //             return block;
       //         }
       //     }

       //     return null;
       // }

       // private IterationStatement LookupContinueTarget() {
       //     for (BreakableStatement block = _breakableBlock; block != null; block = block.Parent) {
       //         IterationStatement target = block as IterationStatement;
       //         if (target != null) {
       //             return target;
       //         }
       //     }

       //     return null;
       // }

       // private IterationStatement LookupContinueTarget(string name) {
       //     for (BreakableStatement block = _breakableBlock; block != null; block = block.Parent) {
       //         IterationStatement target = block as IterationStatement;
       //         if (target != null && block.Labels.Contains(name)) {
       //             return target;
       //         }
       //     }

       //     return null;
       // }

       // void DefineSymbol(TokenType declType, bool disallowIn, string name) {
       //     IScopeNode lastBlock = _currentScope.GetDefinedBlock(name);
       //     if (lastBlock != null && (declType == TokenType.Const || lastBlock.GetSymbol(name) == TokenType.Const)) {
       //         Error(Messages.ConstMultiDeclared, name);
       //     } else {
       //         switch (declType) {
       //             case TokenType.Var:
       //             case TokenType.Const:
       //             case TokenType.Function:
       //                 if (lastBlock != null) {

       //                     if (IsStrictMode) {
       //                         switch (lastBlock.GetSymbol(name)) {
       //                             case TokenType.Var:

       //                                 WarningStrict(Messages.VarMultiDeclared, name);
       //                                 break;

       //                             case TokenType.LParam:
       //                                 WarningStrict(Messages.VarHideArguments, name);
       //                                 break;
       //                         }
       //                     }
       //                 } else {
       //                     _currentScope.AddSymbol(name, declType);
       //                 }
       //                 break;

       //             case TokenType.LParam:
       //                 if (lastBlock != null) {
       //                     // must be duplicate parameter. Second parameter hides the 
       //                     // first, so go ahead and add the second pararameter
       //                     Warn(Messages.DumpParam, name);
       //                 }
       //                 _currentScope.AddSymbol(name, declType);
       //                 break;
       //             case TokenType.Let:
       //                 if (lastBlock != null && lastBlock.GetSymbol(name) == TokenType.Let) {
       //                     Error(Messages.DumpParam, name);
       //                 }
       //                 _currentScope.AddSymbol(name, declType);
       //                 break;

       //             default:
       //                 break;
       //         }
       //     }
       // }

       // #endregion

       // #region 语句

       // private void ParseProgram(IScopeNode script) {

       //     //  Program : See clause 14
       //     //    SourceElements

       //     _currentScope = script;

       //     ParseSourceElements(false);

       // }

       // private void ParseSourceElements(bool inFunction) {

       //     //  SourceElements : See clause 14
       //     //    SourceElement
       //     //    SourceElements SourceElement

       //     //  SourceElement : See clause 14
       //     //    Statement
       //     //    FunctionDeclaration

       //     Statement node = null;
       //     for (; ; ) {
       //         switch (_scanner.Peek().Type) {
       //             case TokenType.Function:
       //                 node = ParseFunctionDeclaration();
       //                 break;

       //             case TokenType.RBrace:
       //                 if (inFunction) {
       //                     return;
       //                 }
       //                 goto default;
       //             case TokenType.EOS:
       //                 return;

       //             default:
       //                 node = ParseStatement();
       //                 break;
       //         }
       //         _currentScope.Statements.Add(node);

       //         if (_checkStrictMode) {
       //             ExpressionStatement e = node as ExpressionStatement;
       //             if (e != null && e.Expression is StringLiteral && ((StringLiteral)e.Expression).Value == "use strict") {
       //                 IsStrictMode = true;
       //             }

       //             _checkStrictMode = false;
       //         }
       //     }

       // }

       // private Statement ParseStatement() {
       //     Statement pn = ParseStatement(null);
       //     if (IsStrictMode && !pn.HasSideEffects)
       //         WarningStrict(Messages.HasSideEffects);
       //     return pn;
       // }

       // private Statement ParseStatement(LabelSet statementLabel) {

       //     //  Statement : See clause 12
       //     //    Block
       //     //    VariableStatement
       //     //    EmptyStatement
       //     //    ExpressionStatement
       //     //    IfStatement
       //     //    IterationStatement
       //     //    ContinueStatement
       //     //    BreakStatement
       //     //    ReturnStatement
       //     //    WithStatement
       //     //    LabelledStatement
       //     //    SwitchStatement
       //     //    ThrowStatement
       //     //    TryStatement

       //     Statement pn;
       //     TokenType tokenType = _scanner.Peek().Type;


       //     switch (tokenType) {

       //         case TokenType.LBrace:
       //             return ParseBlock();

       //         case TokenType.Var:
       //             return ParseVariableStatement(false);

       //         case TokenType.If:
       //             return ParseIfStatement();

       //         case TokenType.Switch:
       //             return ParseSwitchStatement(statementLabel);

       //         case TokenType.While:
       //             return ParseWhileStatement(statementLabel);

       //         case TokenType.Do:
       //             return ParseDoWhileStatement(statementLabel);

       //         case TokenType.For:
       //             return ParseForStatement(statementLabel);

       //         case TokenType.Try:
       //             return ParseTryStatement();

       //         case TokenType.Throw:
       //             pn = ParseThrowStatement();
       //             break;

       //         case TokenType.Break:
       //             pn = ParseBreakStatement();
       //             break;

       //         case TokenType.Continue:
       //             pn = ParseContinueStatement();
       //             break;

       //         case TokenType.With:
       //             return ParseWithStatement();

       //         //case TokenType.Let:
       //         //    return ParseLetStatement();

       //         case TokenType.Return:
       //             pn = ParseReturnStatement();
       //             break;

       //         //case TokenType.Yield:
       //         //    pn = new ExpressionStatement(ParseYieldExpression(tokenType, false));
       //         //    CheckExpressionStatement();
       //         //    break;

       //         case TokenType.Debugger:
       //             pn = ParseDebuggerStatement();
       //             break;

       //         case TokenType.EOS:
       //             return new EmptyStatement(_scanner.CurrentToken.StartLocation);

       //         // Fall thru, to have a node for error recovery to work on
       //         case TokenType.Semicolon:
       //             return new Semicolon(_scanner.Read().StartLocation);

       //         case TokenType.Function:
       //             return ParseFunctionDeclaration();

       //         case TokenType.Const:
       //             goto case TokenType.Var;

       //         //case TokenType.Default:
       //         //    break;

       //         case TokenType.Identifier: {
       //                 string name = _scanner.PeekToken.Literal;
       //               //  _checkTokenLabel = true;
       //                 //  SetCheckForLabel();
       //                 Expression pn2 = ParseExpression(false);

       //                 Identifier id = pn2 as Identifier;

       //                 if (id == null || _scanner.Peek().Type != TokenType.Colon) {
       //                     pn = new ExpressionStatement(pn2);
       //                     CheckExpressionStatement(false);
       //                 } else {
       //                     return ParseLabelledStatement(statementLabel, id);
       //                 }

       //                 break;
       //             }

       //         case TokenType.Illegal:
       //             _scanner.Read();
       //             Error(_scanner.LastErrorMessage);
       //             return ParseStatement();

       //         default:
       //             pn = ParseExpressionStatement(false);
       //             break;
       //     }

       //     switch (_scanner.Peek().Type) {
       //         case TokenType.Semicolon:
       //             pn.EndsWithSemicolon = true;
       //             _scanner.Read();
       //             break;

       //     }
       //     return pn;
       // }

       // private Statement ParseStatementNotEmpty() {
       //     Statement s = ParseStatement();

       //     if (s is EmptyStatement && !(s is Semicolon)) {
       //         Error(Messages.NoBlock);
       //     }

       //     if(!(s is Block)){
       //         if (MatchToken(TokenType.Semicolon))
       //             s.EndsWithSemicolon = true;
       //     }

       //     return s;
       // }

       // private FunctionDeclaration ParseFunctionDeclaration() {

       //     //  FunctionDeclaration : See clause 13
       //     //    function Identifier ( FormalParameterListopt ) { FunctionBody }

       //     FunctionDeclaration fn = new FunctionDeclaration(ParseFunctionExpression(FunctionType.Statement));

       //     _currentScope.AddFunction(fn);

       //     return fn;
       // }

       // private DebuggerStatement ParseDebuggerStatement() {

       //     //  DebuggerStatement:
       //     //     debugger

       //     Location current = _scanner.Read().StartLocation;
       //     MatchToken(TokenType.Semicolon);
       //     return new DebuggerStatement(current, _scanner.CurrentToken.EndLocation);
       // }

       // private Block ParseBlock() {

       //     //  Block : See 12.1
       //     //    { StatementListopt }

       //     //  StatementList :
       //     //    Statement
       //     //    StatementList Statement


       //     Block block = new Block(null,    _scanner.Read().StartLocation);
       //     EnterBlock(block);
       //     try {

       //         while (_scanner.Peek().Type != TokenType.RBrace)
       //             block.Statements.Add(ParseStatement());

       //         ExpectToken(TokenType.RBrace);

       //     } finally {
       //         block.endLocation = _scanner.CurrentToken.EndLocation;
       //         ExitBlock();
       //     }

       //     return block;
       // }

       // //private Expression ParseFunctionExpression() {
       // //    throw new NotImplementedException();
       // //}

       // //private Statement ParseFunctionStatement() {
       // //    throw new NotImplementedException();
       // //}

       // private List<Identifier> ParseFormalParameterList() {

       //     //  FormalParameterList : See clause 13
       //     //    Identifier
       //     //    FormalParameterList , Identifier


       //     ExpectToken(TokenType.LParam);
       //     List<Identifier> args = new List<Identifier>();
       // redo:
       //     switch (_scanner.Read().Type) {
       //         case TokenType.Identifier:
       //             TokenInfo tk = _scanner.CurrentToken;
       //             string s = tk.Literal;
       //             DefineSymbol(TokenType.Function, true, s);

       //             if (IsStrictMode && args.Find(i => i.Name == s) != null) {
       //                 WarningStrict(Messages.DumpParam, s);
       //             }
       //             args.Add(new Identifier(s, tk.StartLocation));
       //             break;

       //         case TokenType.RParam:
       //             return args;

       //         default:
       //             Error(Messages.NoParam);
       //             break;


       //     }

       //     if (MatchToken(TokenType.Comma))
       //         goto redo;

       //     ExpectToken(TokenType.RParam);
       //     return args;


       // }

       // private FunctionExpression ParseFunctionExpression(FunctionType functionType) {

       //     //  FunctionExpression :   See clause 13
       //     //    function Identifieropt ( FormalParameterListopt ) { FunctionBody }

       //     _checkStrictMode = true;

       //     Location current = _scanner.Read().StartLocation;
       //     string name;

       //     //  function f()
       //     if (MatchToken(TokenType.Identifier)) {
       //         name = _scanner.CurrentToken.Literal;

       //     } else {
       //         name = null;
       //     }

       //     // 函数的定义，作为变量定义。
       //     if (functionType == FunctionType.Statement) {
       //         if (name == null) {
       //             if (MatchToken(TokenType.Illegal) || MatchToken(TokenType.NumberLiteral)) {
       //                 MatchToken(TokenType.Identifier);
       //                 Error(Messages.InvalidName);
       //             } else {
       //                 Error(Messages.NoFuncName);
       //             }
       //             name = String.Empty;
       //         }
       //         DefineSymbol(TokenType.Function, false, name);
       //     }

       //     List<Identifier> args = ParseFormalParameterList();

       //     FunctionExpression fn = new FunctionExpression(name, args, current);

       //     // 重新赋予 break 语句。
       //     BreakableStatement savedBreakableBlock = _breakableBlock;
       //     _breakableBlock = null;

       //     // 重新绑定 currentScope 。
       //     IScopeNode savedScript = _currentScope;
       //     _currentScope = fn;

       //     //Node destructuring = null;
       //     //Node body;
       //     try {
       //         ParseFunctionBody();


       //         fn.endLocation = _scanner.CurrentToken.EndLocation;





       //     } finally {
       //         _breakableBlock = savedBreakableBlock;
       //         _currentScope = savedScript;

       //     }

       //     return fn;
       // }

       // private IfStatement ParseIfStatement() {

       //     //  IfStatement : See 12.5
       //     //    if ( Expression ) Statement else Statement
       //     //    if ( Expression ) Statement

       //     Location current = _scanner.Read().StartLocation;

       //     Expression condition = ParseCondition();
       //     Statement ifTrue = ParseStatementNotEmpty();
       //     Statement ifFalse = null;
       //     if (MatchToken(TokenType.Else)) {
       //         ifFalse = ParseStatementNotEmpty();
       //     } else {
       //         ifFalse = new EmptyStatement(_scanner.CurrentToken.EndLocation);
       //     }
       //     return new IfStatement(condition, ifTrue, ifFalse, current, _scanner.CurrentToken.EndLocation);
       // }

       // private Expression ParseCondition() {

       //     // Condition :
       //     //    ( Expression )

       //     ExpectToken(TokenType.LParam);
       //     Expression pn = ParseExpression(false);
       //     ExpectToken(TokenType.RParam);

       //     // 对 if (a = 7) ... 语句 报错。

       //     if (IsStrictMode && pn is AssignmentExpression) {
       //         Warning(Messages.AssignCondition);
       //     }

       //     return pn;
       // }

       // private SwitchStatement ParseSwitchStatement(LabelSet statementLabel) {

       //     //  SwitchStatement :
       //     //    switch ( Expression ) CaseBlock

       //     // CaseBlock :
       //     //    { CaseClausesopt }
       //     //    { CaseClausesopt DefaultClause CaseClausesopt }

       //     //  CaseClauses :
       //     //    CaseClause
       //     //    CaseClauses CaseClause

       //     // CaseClause :
       //     //    case Expression : StatementListopt

       //     // DefaultClause :
       //     //    default : StatementListopt

       //     Location current = _scanner.Read().StartLocation;
       //     ExpectToken(TokenType.LParam);
       //     SwitchStatement pn = new SwitchStatement(statementLabel, new NodeList<CaseClause>(), ParseExpression(false), current);

       //     EnterBlock(pn);
       //     try {
       //         ExpectToken(TokenType.RParam);
       //         ExpectToken(TokenType.LBrace);

       //         bool hasDefault = false;
       //         for (; ; ) {
       //             Expression ep;
       //             TokenInfo tk = _scanner.Read();
       //             current = tk.StartLocation;
       //             TokenType tokenType = tk.Type;
       //             switch (tokenType) {
       //                 case TokenType.Case:
       //                     ep = ParseExpression(false);
       //                     ExpectToken(TokenType.Colon);
       //                     break;

       //                 case TokenType.Default:
       //                     if (hasDefault) {
       //                         Error(Messages.MultiDefault);
       //                     } else {
       //                         hasDefault = true;
       //                     }
       //                     ep = null;
       //                     ExpectToken(TokenType.Colon);
       //                     break;

       //                 case TokenType.RBrace:
       //                     goto endLoop;

       //                 default:
       //                     Error(Messages.BadSwitch);
       //                     goto endLoop;
       //             }


       //             CaseClause   caseExpression = new CaseClause(ep, current, _scanner.CurrentToken.EndLocation);
       //             while ((tokenType = _scanner.Peek().Type) != TokenType.RBrace
       //                    && tokenType != TokenType.Case
       //                    && tokenType != TokenType.Default
       //                    && tokenType != TokenType.EOS) {
       //                        caseExpression.Statements.Add(ParseStatement());
       //             }

       //             pn.Cases.Add(caseExpression);
       //         }


       //     endLoop:
       //         pn.endLocation = _scanner.CurrentToken.EndLocation;
       //     } finally {
       //         ExitBlock();
       //     }
       //     return pn;
       // }

       // private WhileStatement ParseWhileStatement(LabelSet statementLabel) {

       //     // WhileStatement :
       //     //   while ( Expression ) Statement

       //     WhileStatement pn = new WhileStatement(statementLabel, _scanner.Read().StartLocation);
            
       //     EnterBlock(pn);
       //     try {
       //         pn.Condition = ParseCondition();
       //         pn.Body = ParseStatementNotEmpty();
       //         return pn;
       //     } finally {
       //         ExitBlock();
       //     }
       // }

       // private DoWhileStatement ParseDoWhileStatement(LabelSet statementLabel) {

       //     // DoWhileStatement :
       //     //   do Statement while ( Expression );

       //     DoWhileStatement pn = new DoWhileStatement(statementLabel, _scanner.Read().StartLocation);

       //     EnterBlock(pn);

       //     try {
       //         pn.Body = ParseStatementNotEmpty();
       //         ExpectToken(TokenType.While);
       //         pn.Condition = ParseCondition();

       //         pn.endLocation = _scanner.CurrentToken.EndLocation;
       //     } finally {
       //         ExitBlock();
       //     }


       //     MatchToken(TokenType.Semicolon);

       //     pn.endLocation = _scanner.CurrentToken.EndLocation;



       //     return pn;
       // }

       // private IterationStatement ParseForStatement(LabelSet statementLabel) {

       //     //  ForStatement :
       //     //    for (ExpressionNoInopt; Expressionopt ; Expressionopt ) Statement
       //     //    for ( var VariableDeclarationListNoIn; Expressionopt ; Expressionopt ) Statement
       //     //    for ( LeftHandSideExpression in Expression ) Statement
       //     //    for ( var VariableDeclarationNoIn in Expression ) Statement

       //     Location current = _scanner.Read().StartLocation;

       //     IterationStatement np;
       //     Statement initStatement;
       //     Expression condition;
       //     Expression nextStatement = null;

       //     ExpectToken(TokenType.LParam);

       //     switch (_scanner.Peek().Type) {
       //         case TokenType.Semicolon:
       //             initStatement = new EmptyStatement(_scanner.CurrentToken.EndLocation);
       //             break;

       //         case TokenType.Var:
       //         case TokenType.Let:
       //             initStatement = ParseVariableStatement(true);
       //             break;

       //         default:
       //             initStatement = ParseExpressionStatement(true);
       //             break;

       //     }

       //     // 检查 for( in )
       //     if (MatchToken(TokenType.In)) {

       //         // 目标对象。
       //         condition = ParseExpression(false);

       //         np = new ForInStatement(statementLabel, initStatement, condition, current);


       //     } else {
       //         // for (;;)
       //         ExpectToken(TokenType.Semicolon);
       //         if (_scanner.Peek().Type == TokenType.Semicolon) {
       //             // no loop condition
       //             condition = new UndefinedExpression();
       //         } else {
       //             condition = ParseExpression(false);
       //         }

       //         ExpectToken(TokenType.Semicolon);
       //         if (_scanner.Peek().Type == TokenType.RParam) {
       //             nextStatement = new UndefinedExpression();
       //         } else {
       //             nextStatement = ParseExpression(false);
       //         }

       //         np = new ForStatement(statementLabel, initStatement, condition, nextStatement, current);
       //     }


       //     ExpectToken(TokenType.RParam);

       //     EnterBlock(np);

       //     try {
       //         np.Body = ParseStatementNotEmpty();


       //     } finally {
       //         ExitBlock();
       //     }

       //     return np;
       // }

       // private TryStatement ParseTryStatement() {

       //     // try {
       //     //   ...
       //     // } catch(e) {
       //     //   ...
       //     // } finally {
       //     //   ...
       //     // }

       //     // 跳过 try
       //     Location current = _scanner.Read().StartLocation;

       //     AssertToken(TokenType.LBrace);


       //     Block tryblock = ParseBlock();

       //     string varName = null;

       //     Block catchblock = null;

       //     Block finallyblock = null;

       // redo:

       //     switch (_scanner.Peek().Type) {
       //         case TokenType.Catch:
       //             if (catchblock != null) {
       //                 Error(Messages.MultiCatch);
       //             }

       //             _scanner.Read();
       //             ExpectToken(TokenType.LParam);

       //             ExpectToken(TokenType.Identifier);
       //             varName = _scanner.CurrentToken.Literal;

       //             ExpectToken(TokenType.RParam);

       //             catchblock = ParseBlock();

       //             goto redo;

       //         case TokenType.Finally:
       //             _scanner.Read();
       //             finallyblock = ParseBlock();
       //             break;
       //     }

       // if (finallyblock == null) {

       //     if (catchblock == null) {
       //         Error(Messages.NoCatchOrFinally);
       //         catchblock = new Block();
       //     }
       //     return new TryCatchStatement(tryblock, varName, catchblock, current);

       // }

       //     if (catchblock == null)
       //         return new TryFinallyStatement(tryblock, finallyblock, current);

       //     return new TryCatchFinallyStatement(tryblock, varName, catchblock, finallyblock, current);



       // }

       // private ThrowStatement ParseThrowStatement() {

       //     //  ThrowStatement :
       //     //    throw [no LineTerminator here] Expression ;

       //     Location current = _scanner.Read().StartLocation;
       //     if (_scanner.HasLineTerminatorBeforeNext) {
       //         // ECMAScript does not allow new lines before throw expression,
       //         // see bug 256617
       //         //  Error("msg.bad.throw.eol");
       //         return new ThrowStatement(new UndefinedExpression(current), current);
       //     }

       //     return new ThrowStatement(ParseExpression(false), current);
       // }

       // private BreakStatement ParseBreakStatement() {

       //     //  BreakStatement : See 12.8
       //     //    break [no LineTerminator here] Identifieropt ;

       //     Location current = _scanner.Read().StartLocation;

       //     BreakableStatement target;

       //     string label;

       //     if(!_scanner.HasLineTerminatorBeforeNext && MatchToken(TokenType.Identifier)){
       //         label = _scanner.CurrentToken.Literal;
       //         target = LookupBreakTarget(label);
       //     } else {
       //         target = LookupBreakTarget();
       //         label = null;
       //     }


       //     if (target == null) {
       //         if (label == null)
       //             Error(Messages.UnexpectedToken, "break");
       //         else
       //             Error(Messages.BadBreak);
       //     }

       //     return new BreakStatement(target, label, current, _scanner.CurrentToken.EndLocation);
       // }

       // private Statement ParseContinueStatement() {

       //     //  ContinueStatement : See 12.7
       //     //    continue [no LineTerminator here] Identifieropt ;

       //     Location current = _scanner.Read().StartLocation;

       //     IterationStatement target;

       //     string label;

       //     if (!_scanner.HasLineTerminatorBeforeNext && MatchToken(TokenType.Identifier)) {
       //         label = _scanner.CurrentToken.Literal;
       //         target = LookupContinueTarget(label);
       //     } else {
       //         target = LookupContinueTarget();
       //         label = null;
       //     }


       //     if (target == null) {
       //         if (label == null)
       //             Error(Messages.UnexpectedToken, "continue");
       //         else
       //             Error(Messages.BadContinue);
       //     }

       //     return new ContinueStatement(target, label, current, _scanner.CurrentToken.EndLocation);
       // }

       // private Statement ParseWithStatement() {

       //     //  WithStatement : See 12.10
       //     //    with ( Expression ) Statement

       //     if (IsStrictMode) {
       //         WarningStrict(Messages.NoWith);
       //     }

       //     Location c = _scanner.Read().StartLocation;

       //     ExpectToken(TokenType.LParam);

       //     Expression expression = ParseExpression(false);

       //     ExpectToken(TokenType.RParam);

       //     WithStatement s = new WithStatement(expression, c);

       //     s.Body = ParseStatementNotEmpty();

       //     s.endLocation = _scanner.CurrentToken.EndLocation;

       //     return s;
       // }

       // private Statement ParseLetStatement() {
       //     throw new NotSupportedException();
       // }

       // private ReturnStatement ParseReturnStatement() {

       //     //  ReturnStatement : See 12.9
       //     //    return [no LineTerminator here] Expressionopt ;

       //     if(!(_currentScope is FunctionExpression)){
       //         Error(Messages.UnexpectedToken, "return");
       //     }

       //     Location current =  _scanner.Read().StartLocation;

       //     Expression e;
       //     if (!_scanner.HasLineTerminatorBeforeNext) {
       //         switch (_scanner.Peek().Type) {
       //             case TokenType.Semicolon:
       //             case TokenType.RBrace:
       //             case TokenType.EOS:
       //             case TokenType.Yield:
       //             case TokenType.RBrack:

       //                 e = null;
       //                 break;

       //             default:
       //                 e = ParseExpression(false);
       //                 break;
       //         }


       //     } else {
       //         e = null;
       //     }

       //     return new ReturnStatement(e, current, _scanner.CurrentToken.EndLocation);
       // }

       // private ExpressionStatement ParseExpressionStatement(bool disallowIn) {

       //     //  ExpressionStatement : See 12.4
       //     //    [lookahead ∉ {{, function}] Expression ;

       //     // 已经在 ParseStatement 处理 { ， function

       //     ExpressionStatement ep =  new ExpressionStatement(ParseExpression(disallowIn));

       //     CheckExpressionStatement(disallowIn);
            
       //     return ep;
       // }

       // void CheckExpressionStatement(bool disallowIn) {
       //     if (!_scanner.HasLineTerminatorBeforeNext) {
       //         switch(_scanner.Peek().Type){
       //             case TokenType.Semicolon:
       //             case TokenType.EOS:
       //             case TokenType.RBrace:
       //                 break;

       //             case TokenType.In:
       //                 if (disallowIn)
       //                     break;

       //                 goto default;

       //             default:
       //                 Error(Messages.UnexpectedToken, Token.IsSymbol(_scanner.Peek().Type) ? Token.Find(_scanner.Peek().Type).Name : _scanner.Peek().Literal);
       //                 break;
       //         }
       //     }
       // }

       // private LabelledStatement ParseLabelledStatement(LabelSet statementLabel, Identifier id) {

       //     //  LabelledStatement : See 12.12
       //     //    Identifier : Statement

       //     //if (scanner.Peek().Type != TokenType.Colon) {
       //     //    Error("标识符后必须是冒号");
       //     //}
       //     _scanner.Read();

       //     // 如果没有 label，马上创建。
       //     if (statementLabel == null) {
       //         statementLabel = new LabelSet();
       //     }

       //     // 只对下个语句才有效。
       //     statementLabel.Add(id);

       //     try {
       //         return new LabelledStatement(id, ParseStatement(statementLabel));
       //     } finally {
       //         statementLabel.Remove(id);
       //     }


       // }

       // #endregion

       // #region 表达式

       // /// <summary>
       // /// 解析表达式。
       // /// </summary>
       // /// <param name="disallowIn">是否在 for 初始化区。</param>
       // /// <returns>表达式节点。</returns>
       // private Expression ParseExpression(bool disallowIn) {

       //     //Expression : See 11.14
       //     //    AssignmentExpression
       //     //    Expression , AssignmentExpression


       //     Expression pn = ParseAssignmentExpression(disallowIn);
       //     while (MatchToken(TokenType.Comma)) {
       //         if (IsStrictMode && !pn.HasSideEffects)
       //             WarningStrict(Messages.HasSideEffects);
       //         if (_scanner.Peek().Type == TokenType.Yield) {
       //             Error(Messages.UnexpectedToken, "yield");
       //         }
       //         pn = new CommaExpression(pn, ParseAssignmentExpression(disallowIn));
       //     }
       //     return pn;
       // }

       // private Expression ParseAssignmentExpression(bool disallowIn) {

       //     // AssignmentExpression : See 11.13
       //     //   ConditionalExpression
       //     //   LeftHandSideExpression AssignmentOperator AssignmentExpression

       //     if (_scanner.Peek().Type == TokenType.Yield) {
       //         _scanner.Read();
       //         return ParseYieldExpression(TokenType.Yield, true);
       //     }
       //     Expression pn = ParseConditionalExpression(disallowIn);

       //     TokenType tokenType = _scanner.Peek().Type;
       //     if (TokenType.Assign <= tokenType && tokenType <= TokenType.AssignMod) {
       //         _scanner.Read();
       //         pn = new AssignmentExpression(tokenType, pn, ParseAssignmentExpression(disallowIn));
       //     }

       //     return pn;
       // }

       // private Expression ParseConditionalExpression(bool disallowIn) {

       //     //  ConditionalExpression : See 11.12
       //     //    LogicalORExpression
       //     //    LogicalORExpression ? AssignmentExpression : AssignmentExpression

       //     Expression condition = ParseLogicalORExpression(disallowIn);

       //     if (MatchToken(TokenType.Conditional)) {
       //         Expression trueExpression = ParseAssignmentExpression(false);
       //         ExpectToken(TokenType.Colon);
       //         Expression falseExpression = ParseAssignmentExpression(disallowIn);
       //         return new ConditionalExpression(condition, trueExpression, falseExpression);
       //     }

       //     return condition;


       // }

       // private Expression ParseLogicalORExpression(bool disallowIn) {

       //     //  LogicalORExpression : See 11.11
       //     //    LogicalANDExpression
       //     //    LogicalORExpression || LogicalANDExpression

       //     Expression pn = ParseLogicalANDExpression(disallowIn);
       //     if (MatchToken(TokenType.Or)) {
       //         pn = new LogicalExpression(pn, TokenType.Or, ParseLogicalORExpression(disallowIn));
       //     }

       //     return pn;
       // }

       // private Expression ParseLogicalANDExpression(bool disallowIn) {

       //     //  LogicalANDExpression : See 11.11
       //     //    BitwiseORExpression
       //     //    LogicalANDExpression && BitwiseORExpression

       //     Expression pn = ParseBitwiseORExpression(disallowIn);
       //     if (MatchToken(TokenType.And)) {
       //         pn = new LogicalExpression(pn, TokenType.And, ParseLogicalANDExpression(disallowIn));
       //     }

       //     return pn;
       // }

       // private Expression ParseBitwiseORExpression(bool disallowIn) {

       //     //  BitwiseORExpression : See 11.10
       //     //    BitwiseXORExpression
       //     //    BitwiseORExpression | BitwiseXORExpression

       //     Expression pn = ParseBitwiseXORExpression(disallowIn);
       //     while (MatchToken(TokenType.BitOr)) {
       //         pn = new BitwiseExpression(pn, TokenType.BitOr, ParseBitwiseXORExpression(disallowIn));
       //     }
       //     return pn;
       // }

       // private Expression ParseBitwiseXORExpression(bool disallowIn) {

       //     //  BitwiseXORExpression : See 11.10
       //     //    BitwiseANDExpression
       //     //    BitwiseORExpression ^ BitwiseANDExpression

       //     Expression pn = ParseBitwiseANDExpression(disallowIn);
       //     while (MatchToken(TokenType.BitXor)) {
       //         pn = new BitwiseExpression(pn, TokenType.BitXor, ParseBitwiseANDExpression(disallowIn));
       //     }
       //     return pn;
       // }

       // private Expression ParseBitwiseANDExpression(bool disallowIn) {

       //     //  BitwiseANDExpression : See 11.10
       //     //    EqualityExpression
       //     //    BitwiseANDExpression & EqualityExpression

       //     Expression pn = ParseEqualityExpression(disallowIn);
       //     while (MatchToken(TokenType.BitAnd)) {
       //         pn = new BitwiseExpression(pn, TokenType.BitAnd, ParseEqualityExpression(disallowIn));
       //     }
       //     return pn;
       // }

       // private Expression ParseEqualityExpression(bool disallowIn) {

       //     //  EqualityExpression : See 11.9
       //     //    RelationalExpression
       //     //    EqualityExpression == RelationalExpression
       //     //    EqualityExpression != RelationalExpression
       //     //    EqualityExpression === RelationalExpression
       //     //    EqualityExpression !== RelationalExpression

       //     Expression pn = ParseRelationalExpression(disallowIn);
       // redo:
       //     switch (_scanner.Peek().Type) {
       //         case TokenType.Eq:
       //         case TokenType.Ne:
       //         case TokenType.EqStrict:
       //         case TokenType.NeStrict:
       //             pn = new EqualityExpression(pn, _scanner.Read().Type, ParseRelationalExpression(disallowIn));
       //             goto redo;
       //     }
       //     return pn;
       // }

       // private Expression ParseRelationalExpression(bool disallowIn) {

       //     //  RelationalExpression : See 11.8
       //     //    ShiftExpression
       //     //    RelationalExpression < ShiftExpression
       //     //    RelationalExpression > ShiftExpression
       //     //    RelationalExpression <= ShiftExpression
       //     //    RelationalExpression >= ShiftExpression
       //     //    RelationalExpression instanceof ShiftExpression
       //     //    RelationalExpression in ShiftExpression

       //     Expression pn = ParseShiftExpression();
       // redo:
       //     TokenType tokenType = _scanner.Peek().Type;
       //     switch (tokenType) {
       //         case TokenType.In:
       //             if (disallowIn)
       //                 break;

       //             goto case TokenType.Gt;
       //         case TokenType.Instanceof:
       //         case TokenType.Lte:
       //         case TokenType.Lt:
       //         case TokenType.Gte:
       //         case TokenType.Gt:
       //             _scanner.Read();
       //             pn = new RelationalExpression(pn, tokenType, ParseShiftExpression());
       //             goto redo;
       //     }
       //     return pn;
       // }

       // private Expression ParseShiftExpression() {

       //     //  ShiftExpression : See 11.7
       //     //    AdditiveExpression
       //     //    ShiftExpression << AdditiveExpression
       //     //    ShiftExpression >> AdditiveExpression
       //     //    ShiftExpression >>> AdditiveExpression

       //     Expression pn = ParseAdditiveExpression();
       // redo:
       //     TokenType tokenType = _scanner.Peek().Type;
       //     switch (tokenType) {
       //         case TokenType.Shl:
       //         case TokenType.Sar:
       //         case TokenType.Shr:
       //             _scanner.Read();
       //             pn = new ShiftExpression(pn, tokenType, ParseAdditiveExpression());
       //             goto redo;
       //     }
       //     return pn;
       // }

       // private Expression ParseAdditiveExpression() {

       //     //  AdditiveExpression : See 11.6
       //     //    MultiplicativeExpression
       //     //    AdditiveExpression + MultiplicativeExpression
       //     //    AdditiveExpression - MultiplicativeExpression

       //     Expression pn = ParseMultiplicativeExpression();
       // redo:
       //     TokenType tokenType = _scanner.Peek().Type;
       //     if (tokenType == TokenType.Add || tokenType == TokenType.Sub) {
       //         _scanner.Read();
       //         // flushNewLines
       //         pn = new AdditiveExpression(pn, tokenType, ParseMultiplicativeExpression());
       //         goto redo;
       //     }

       //     return pn;
       // }

       // private Expression ParseMultiplicativeExpression() {

       //     //  MultiplicativeExpression : See 11.5
       //     //    UnaryExpression
       //     //    MultiplicativeExpression * UnaryExpression
       //     //    MultiplicativeExpression / UnaryExpression
       //     //    MultiplicativeExpression % UnaryExpression

       //     Expression pn = ParseUnaryExpression();
       // redo:
       //     TokenType tokenType = _scanner.Peek().Type;
       //     switch (tokenType) {
       //         case TokenType.Mul:
       //         case TokenType.Div:
       //         case TokenType.Mod:
       //             _scanner.Read();
       //             pn = new MultiplicativeExpression(pn, tokenType, ParseUnaryExpression());
       //             goto redo;
       //     }

       //     return pn;
       // }

       // private Expression ParseUnaryExpression() {

       //     //  UnaryExpression : See 11.4
       //     //    PostfixExpression
       //     //    delete UnaryExpression
       //     //    void UnaryExpression
       //     //    typeof UnaryExpression
       //     //    ++ UnaryExpression
       //     //    -- UnaryExpression
       //     //    + UnaryExpression
       //     //    - UnaryExpression
       //     //    ~ UnaryExpression
       //     //    ! UnaryExpression

       //     TokenType tokenType = _scanner.Peek().Type;

       //     switch (tokenType) {
       //         case TokenType.Void:
       //         case TokenType.Not:
       //         case TokenType.BitNot:
       //         case TokenType.Typeof:
       //         case TokenType.Add:
       //         case TokenType.Sub:
       //         case TokenType.Delete:
       //             _scanner.Read();
       //             Location current1 = _scanner.CurrentToken.StartLocation;
       //             return new UnaryExpression(tokenType, ParseUnaryExpression(), current1);

       //         case TokenType.Inc:
       //         case TokenType.Dec:
       //             _scanner.Read();
       //             Location current2 = _scanner.CurrentToken.StartLocation;
       //             return new IncrementOperation(ParseMemberExpression(true), tokenType, current2);

       //         //case TokenType.Lt:
       //             //   return ParseXmlInitializer();

       //         default:
       //             return ParsePostfixExpression();
       //     }

       // }

       // private Expression ParseXmlInitializer() {
       //     throw new NotSupportedException();
       // }

       // private ArgumentList ParseArguments() {

       //     //  Arguments : See 11.2
       //     //    ( )
       //     //    ( ArgumentList )

       //     ExpectToken(TokenType.LParam);

       //     bool matched = MatchToken(TokenType.RParam);

       //     ArgumentList arguments = null;
       //     if (!matched) {
       //         arguments = ParseArgumentList();

       //         ExpectToken(TokenType.RParam);
       //     }

       //     return arguments;
       // }

       // private ArgumentList ParseArgumentList() {

       //     //  ArgumentList : See 11.2
       //     //    AssignmentExpression
       //     //    ArgumentList , AssignmentExpression


       //     ArgumentList arguments = new ArgumentList();
       //     do {
       //         switch (_scanner.Peek().Type) {
       //             case TokenType.RParam:
       //                 return arguments;

       //             case TokenType.Yield:
       //                 Error(Messages.UnexpectedToken, "yield");
       //                 break;
       //         }



       //         arguments.Add(ParseAssignmentExpression(false));
       //     } while (MatchToken(TokenType.Comma));

       //     return arguments;

       // }

       // private Expression ParsePostfixExpression() {

       //     //  PostfixExpression : See 11.3
       //     //    LeftHandSideExpression
       //     //    LeftHandSideExpression [no LineTerminator here] ++
       //     //    LeftHandSideExpression [no LineTerminator here] --

       //     Expression pn = ParseLeftHandSideExpression();

       //     if (!_scanner.HasLineTerminatorBeforeNext) {
       //         TokenType type = _scanner.Peek().Type;
       //         if (type == TokenType.Inc || type == TokenType.Dec) {
       //             _scanner.Read();
       //             return new PostfixExpression(pn, type, pn.StartLocation, _scanner.CurrentToken.EndLocation);
       //         }
       //     }

       //     return pn;
       // }

       // private Expression ParseLeftHandSideExpression() {

       //     //  LeftHandSideExpression : See 11.3
       //     //    NewExpression
       //     //    CallExpression

       //     // NewExpression = new NewExpression | MemberExpression
       //     //               = new NewExpression | new MemberExpression Arguments | ..
       //     //               = new (NewExpression | MemberExpression Arguments) | ..

       //     return ParseMemberExpression(true);
       // }

       // private Expression ParseNewExpression(bool allowCallSyntax) {

       //     //  NewExpression : See 11.2
       //     //    MemberExpression
       //     //    new NewExpression

       //     Location current = _scanner.Read().StartLocation;

       //     Expression e = ParseMemberExpression(false);

       //     Expression pn = new NewExpression(e, _scanner.Peek().Type == TokenType.LParam ? ParseArguments() : null, current, _scanner.CurrentToken.EndLocation);

       //     return pn;
       // }

       // private Expression ParseMemberExpression(bool allowCallSyntax) {

       //     //  MemberExpression : See 11.2
       //     //    PrimaryExpression
       //     //    FunctionExpression
       //     //    MemberExpression [ Expression ]
       //     //    MemberExpression . Identifier
       //     //    new MemberExpression Arguments

       //     Expression e;

       //     switch (_scanner.Peek().Type) {
       //         case TokenType.New:
       //             e = ParseNewExpression(allowCallSyntax);
       //             break ;

       //         case TokenType.Function:
       //             e = ParseFunctionExpression(FunctionType.Expression);
       //             break;

       //         default:
       //             e = ParsePrimaryExpression();
       //             break;


       //     }


       //     return ParseCallExpression(allowCallSyntax, e);
       // }

       // private Expression ParseCallExpression(bool allowCallSyntax, Expression pn) {

       //     //  CallExpression : See 11.2
       //     //    MemberExpression Arguments
       //     //    CallExpression Arguments
       //     //    CallExpression [ Expression ]
       //     //    CallExpression . Identifier

       //redo:
       //     switch (_scanner.Peek().Type) {

       //         case TokenType.Period:
       //             _scanner.Read();

       //             ExpectToken(TokenType.Identifier);

       //             pn = new PropertyCallExpression(pn, _scanner.CurrentToken.Literal, _scanner.CurrentToken.EndLocation);
       //             goto redo;

       //         case TokenType.LBrack:
       //             _scanner.Read();
       //             Expression p = ParseExpression(false);
       //             ExpectToken(TokenType.RBrack, Messages.ExpectedArrayIndex);
       //             pn = new IndexCallExpression(pn, p, _scanner.CurrentToken.EndLocation);
       //             goto redo;

       //         case TokenType.LParam:
       //             if (!allowCallSyntax) {
       //                 return pn;
       //             }
       //             _scanner.Read();
       //             ArgumentList args = ParseArgumentList();
       //             ExpectToken(TokenType.RParam);
       //             pn = new FunctionCallExpression(pn, args, _scanner.CurrentToken.EndLocation);
       //             goto redo;

       //         default:
       //             return pn;
       //     }
       // }

       // private ArrayLiteral ParseArrayLiteral() {

       //     //  ArrayLiteral : See 11.1.4
       //     //    [ Elisionopt ]
       //     //    [ ElementList ]
       //     //    [ ElementList , Elisionopt ]

       //     //  ElementList : See 11.1.4
       //     //    Elisionopt AssignmentExpression
       //     //    ElementList , Elisionopt AssignmentExpression

       //     //  Elision : See 11.1.4
       //     //    ,
       //     //    Elision ,

       //     // 已经 处理 [ 

       //     Location current = _scanner.CurrentToken.StartLocation;

       //     NodeList<Expression> values = new NodeList<Expression>();
       //     bool after = true;
       // redo:
       //     switch (_scanner.Peek().Type) {

       //         case TokenType.Comma:
       //             _scanner.Read();
       //             if (!after) {
       //                 after = true;
       //             } else {
       //                 values.Add(new UndefinedExpression(_scanner.CurrentToken.StartLocation));
       //             }

       //             goto redo;
       //         case TokenType.RBrack:
       //             _scanner.Read();
       //             break;

       //         default:
       //             //    if (skipCount == 0 && elems.size() == 1 &&
       //             //           tokenType == TokenType.FOR) {
       //             //    Node scopeNode = nf.createScopeNode(Token.ARRAYCOMP,
       //             //                                        ts.getLineno());
       //             //    String tempName = currentScriptOrFn.getNextTempName();
       //             //    pushScope(scopeNode);
       //             //    try {
       //             //        DefineSymbol(Token.LET, false, tempName);
       //             //        Node expr = (Node)elems.get(0);
       //             //        Node block = nf.createBlock(ts.getLineno());
       //             //        Node init = new Node(Token.EXPR_VOID,
       //             //            nf.createAssignment(Token.ASSIGN,
       //             //                nf.createName(tempName),
       //             //                nf.createCallOrNew(Token.NEW,
       //             //                    nf.createName("Array"))), ts.getLineno());
       //             //        block.addChildToBack(init);
       //             //        block.addChildToBack(ParseArrayComprehension(tempName,
       //             //            expr));
       //             //        scopeNode.addChildToBack(block);
       //             //        scopeNode.addChildToBack(nf.createName(tempName));
       //             //        return scopeNode;
       //             //    } finally {
       //             //        popScope();
       //             //    }
       //             //} else {

       //             if (!after) {
       //                 Error(Messages.NoBracketArgs);
       //             }
       //             values.Add(ParseAssignmentExpression(false));
       //             after = false;


       //             goto redo;
       //         // }
       //     }


       //     return new ArrayLiteral(values, current, _scanner.CurrentToken.EndLocation);
       // }

       // private static bool IsGetterOrSetter(StringBuilder sb) {
       //     return sb.Length == 3 && sb[1] == 'e' && sb[2] == 't' && (sb[0] == 'g' || sb[0] == 's');
       // }

       // /// <summary>
       // /// Parses the object literal.
       // /// </summary>
       // /// <returns></returns>
       // private ObjectLiteral ParseObjectLiteral() {

       //     //  ObjectLiteral : See 11.1.5
       //     //    { }
       //     //    { PropertyNameAndValueList }

       //     //  PropertyNameAndValueList : See 11.1.5
       //     //    PropertyName : AssignmentExpression
       //     //    PropertyNameAndValueList , PropertyName : AssignmentExpression

       //     //  PropertyName : See 11.1.5
       //     //    Identifier
       //     //    StringLiteral
       //     //    NumericLiteral


       //     // 已处理 {

       //     Location current = _scanner.CurrentToken.StartLocation;

       //     NodeList<ObjectLiteral.Property> values = new NodeList<ObjectLiteral.Property>();

       //     if (!MatchToken(TokenType.RBrace)) {


       //         List<string> names = null;
                
       //         if(IsStrictMode)
       //             names = new List<string>();

       //     redo:

       //         TokenInfo tk;
       //         ILiteral key;
       //         Expression value;
       //         ObjectLiteral.PropertyType type = ObjectLiteral.PropertyType.Constant;

       //         string s;

       //         switch (_scanner.Peek().Type) {

       //             // 如果是标识符，检查是否为 get/set
       //             case TokenType.Identifier:
       //                 tk = _scanner.Read();
       //                 if (_scanner.Peek().Type == TokenType.Identifier && IsGetterOrSetter(tk.LiteralBuffer)) {

       //                     type = tk.LiteralBuffer[0] == 'g' ? ObjectLiteral.PropertyType.Getter : ObjectLiteral.PropertyType.Setter;

       //                     //读取下一个。
       //                     tk = _scanner.Peek();

       //                     key = new Identifier(s = tk.Literal, tk.StartLocation);

       //                     value = ParseFunctionExpression(FunctionType.ExpressionStatement);
       //                 } else {
       //                     key = new Identifier(s = tk.Literal, tk.StartLocation);
       //                     value = ParsePlainProperty();
       //                 }
       //                 break;

       //             case TokenType.StringLiteral:
       //                 tk = _scanner.Read();
       //                 key = new StringLiteral(s = tk.Literal, '\"', tk.StartLocation, tk.EndLocation);
       //                 value = ParsePlainProperty();
       //                 break;
       //             case TokenType.CharLiteral:
       //                 tk = _scanner.Read();
       //                 key = new StringLiteral(s = tk.Literal, '\'', tk.StartLocation, tk.EndLocation);
       //                 value = ParsePlainProperty();
       //                 break;


       //             case TokenType.NumberLiteral:
       //             //case TokenType.DecimalLiteral:
       //             //case TokenType.OctalIntegerLiteral:
       //             //case TokenType.HexIntegerLiteral:
       //                 tk = _scanner.Read();
       //                 key = new NumberLiteral(s = tk.Literal, tk.StartLocation);
       //                 value = ParsePlainProperty();
       //                 break;

       //             case TokenType.RBrace:
       //                 // case TokenType.Comma:
       //                 //  允许多余 }
       //                 _scanner.Read();
       //                 goto end;
       //             default:
       //                 Error(Messages.BadPropertyName);
       //                 ExpectToken(TokenType.RBrace);
       //                 goto end;
       //         }

                

       //         if (IsStrictMode) {
       //             if (names.Contains(s))
       //                 WarningStrict(Messages.DumpPropertyName, s);
       //             names.Add(s);
       //         }
                
       //         values.Add(new ObjectLiteral.Property(type, key, value));

       //         // 如果存在下一个属性。
       //         if (MatchToken(TokenType.Comma))
       //             goto redo;

       //         TokenInfo token = _scanner.Peek();

       //         if (token.Type != TokenType.RBrace) {
       //             if (token.Type == TokenType.Identifier || token.Type == TokenType.StringLiteral || token.Type == TokenType.CharLiteral || token.Type == TokenType.NumberLiteral) {
       //                 Error(String.Format(Messages.ExpectedToken, ","));
       //                 goto redo;
       //             } else {
       //                 Error(String.Format(Messages.ExpectedToken, "}"));
       //             }
       //         } else {
       //             _scanner.Read();
       //         }

       //     end: ;
       //     }

       //     return new ObjectLiteral(values, current, _scanner.CurrentToken.EndLocation);
       // }

       // private Expression ParsePrimaryExpression() {

       //     //  PrimaryExpression : See 11.1
       //     //    this
       //     //    Identifier
       //     //    Literal
       //     //    ArrayLiteral
       //     //    ObjectLiteral
       //     //    ( Expression )

       //     //  Literal :: See 7.8
       //     //    NullLiteral
       //     //    BooleanLiteral
       //     //    NumericLiteral
       //     //    StringLiteral

       //     Expression pn;

       //     switch (_scanner.Peek().Type) {

       //         case TokenType.Div:
       //         case TokenType.AssignDiv: {

       //                 // 得到 / 和 /=  后， 解析正则。
       //             Location current = _scanner.PeekToken.StartLocation;
       //                 Scanner js = (Scanner)_scanner;
       //                 string s = js.ScanRegularExpressionBody();
       //                 if ( s != null ) {
       //                     string s2 = js.ScanRegularExpressionFlags();
       //                     return new RegExpLiteral(s, s2, current, _scanner.CurrentToken.EndLocation);
       //                 }
       //                 Error(Messages.BadRegExp);

       //                 break;

       //             }

       //     }

       //     switch (_scanner.Read().Type) {

       //         case TokenType.LBrack:
       //             return ParseArrayLiteral();

       //         case TokenType.LBrace:
       //             return ParseObjectLiteral();

       //         case TokenType.Let:
       //             return ParseLet(false);

       //         case TokenType.LParam:
       //             if (DoParseParamExpression) {
       //                 Location current = _scanner.CurrentToken.StartLocation;
       //                 pn = ParseExpression(false);
       //                 ExpectToken(TokenType.RParam);

       //                 pn = new ParamedExpression(pn, current, _scanner.CurrentToken.EndLocation);
       //             } else {
       //                 pn = ParseExpression(false);
       //                 //   pn.putProp(Node.PARENTHESIZED_PROP, bool.TRUE);
       //                 //  pn.ParamNum++;
       //                 ExpectToken(TokenType.RParam);
       //             }
       //             return pn;

       //         //case TokenType.XmlAttr:
       //         //    return pn;

       //         case TokenType.Identifier: {
       //                 string name = _scanner.CurrentToken.Literal;
       //               //  if (_checkTokenLabel && scanner.Peek().Type == TokenType.Colon) {
       //                     // Do not consume colon, it is used as unwind indicator
       //                     // to return to ParseStatement()Helper.
       //                     // XXX BetokenTypeer way?
       //                  // return new LabelClause(name, scanner.CurrentToken.StartLocation);
       //               //  }

       //                 //  if (compilerEnv.isXmlAvailable()) {
       //                 //      pn = ParsePropertyName(null, name, 0);
       //                 //  } else {
       //                 return new Identifier(name, _scanner.CurrentToken.StartLocation);
       //                 //   }
       //             }

       //         case TokenType.NumberLiteral:
       //             return new NumberLiteral(_scanner.CurrentToken.Literal, _scanner.CurrentToken.StartLocation);

       //         case TokenType.CharLiteral:
       //             return new StringLiteral(_scanner.CurrentToken.Literal, '\'', _scanner.CurrentToken.StartLocation, _scanner.CurrentToken.EndLocation);

       //         case TokenType.StringLiteral:
       //             return new StringLiteral(_scanner.CurrentToken.Literal, '\"', _scanner.CurrentToken.StartLocation, _scanner.CurrentToken.EndLocation);

       //         case TokenType.NullLiteral:
       //             return new NullLiteral(_scanner.CurrentToken.StartLocation);
       //         case TokenType.This:
       //             return new ThisLiteral(_scanner.CurrentToken.StartLocation);
       //         case TokenType.FalseLiteral:
       //             return new FalseLiteral(_scanner.CurrentToken.StartLocation);
       //         case TokenType.TrueLiteral:
       //             return new TrueLiteral(_scanner.CurrentToken.StartLocation);

       //         case TokenType.EOS:
       //             Error(Messages.UnexpectedEOF);
       //             break;

       //         default:
       //             Error(Messages.Syntax);
       //             break;
       //     }
       //     return new UndefinedExpression(_scanner.CurrentToken.StartLocation);
       // }

       // private Expression ParsePlainProperty() {
       //     ExpectToken(TokenType.Colon);



       //     return ParseAssignmentExpression(false);
       // }

       // private Expression ParseYieldExpression(TokenType tokenType, bool eContext) {
       //     throw new NotSupportedException();
       // }


       // /// <summary>
       // /// 解析 var/const/let 内变量的定义。
       // /// </summary>
       // /// <param name="inFor">是否在 for 内。</param>
       // /// <param name="declType">类型。</param>
       // /// <returns>变量定义语句。</returns>
       // private VariableStatement ParseVariableStatement(bool disallowIn) {

       //     //  VariableStatement : See 12.2
       //     //    var VariableDeclarationList ;
       //     //!     const VariableDeclarationList ;

       //     TokenInfo tk = _scanner.Read();

       //     Location current = tk.StartLocation;
       //     NodeList<VariableDeclaration> vars = ParseVariableDeclarationList(disallowIn, tk.Type);

       //     return new VariableStatement(vars, current, _scanner.CurrentToken.EndLocation);
       // }

       // /// <summary>
       // /// 解析变量定义列表。
       // /// </summary>
       // /// <param name="disallowIn">是否在 for 内。</param>
       // /// <param name="declType">类型。</param>
       // /// <returns>变量定义语句。</returns>
       // private NodeList<VariableDeclaration> ParseVariableDeclarationList(bool disallowIn, TokenType declType) {

       //     //  VariableStatement:
       //     //     var VariableDeclarationList;

       //     //  VariableDeclarationList :
       //     //    VariableDeclaration
       //     //    VariableDeclarationList , VariableDeclaration

       //     //  VariableDeclaration :
       //     //    Identifier Initialiseropt

       //     //  Initialiser :
       //     //    = AssignmentExpression

       //     NodeList<VariableDeclaration> vars = new NodeList<VariableDeclaration>();

       // redo:
       //     Identifier name;
       //     TokenInfo tk = _scanner.Read();

       //     switch (tk.Type) {

       //         case TokenType.Identifier:
       //             string s = _scanner.CurrentToken.Literal;
       //             DefineSymbol(declType, disallowIn, s);
       //             name = new Identifier(s, tk.StartLocation);
       //             break;

       //         default:
       //             name = null;
       //             Error(Messages.BadVar);
       //             break;

       //     }

       //     Expression init = null;
       //     if (MatchToken(TokenType.Assign)) {
       //         init = ParseAssignmentExpression(disallowIn);
       //     }

       //     if(name != null)
       //         vars.Add(new VariableDeclaration(name, init));

       //     if (MatchToken(TokenType.Comma))
       //         goto redo;

       //     return vars;
       // }

       // private Expression ParseLet(bool isStatement) {
       //     throw new NotSupportedException();
       // }

       // private void ParseFunctionBody() {

       //     //  FunctionBody : See clause 13
       //     //      SourceElements

       //     ExpectToken(TokenType.LBrace);
       //     ParseSourceElements(true);
       //     ExpectToken(TokenType.RBrace);
       // }

       // #endregion
    }
}
